<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/4/25/025
 * Time: 17:20
 */



class ConsHasher implements \hasher,\distribution
{
    protected $nodes = [];
    protected  $points = [];
    protected $_mul = 64;


    /**对键进行hash运算
     * @param $str （memcached中的键）
     * @return string
     */
    public function _hash($str)
    {
        return sprintf('%u', crc32($str));
    }

    /**根据memcached的键值找出所在服务器代号（如：A、B、C、D、E）
     * @param $key
     * @return mixed
     */
    public function lookup($key)
    {
        $postion = $this->_hash($key);//算出键在圆环上的位置
        reset($this->points);
        $neddle = key($this->points);
        foreach ($this->points as $p=>$v){
            if ($postion <= $p ){
                $neddle = $p;
                break;
            }
        }
        return $this->points[$neddle];
    }

    /**添加服务器节点，算出服务器在圆环上的位置
     * @param $node
     */
    public function addNode($node){
        $this->nodes[$node] = [];
        for ($i=0;$i<$this->_mul;$i++){
            $point = $node.'_'.$i;
            $point = $this->_hash($point); //虚拟节点转为数字
            $this->points[$point] = $node;
            $this->nodes[$node][] = $point;
            $this->resort();
        }
    }

    /**删除服务器节点
     * @param $node
     */
    public function delNode($node){
        foreach ($this->nodes[$node] as $p){//清除64个虚拟节点
            unset($this->points[$p]);
        }
        unset($this->nodes[$node]);//清除节点
    }

    /**
     *对所有节点按顺序排列
     */
    protected function resort(){
        ksort($this->points);
    }
}